package com.xqboss.apps.service.nft;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.constant.RedisKey;
import com.xqboss.apps.domain.nft.Category;
import com.xqboss.apps.domain.nft.Nft;
import com.xqboss.apps.dto.category.CategoryDto;
import com.xqboss.apps.mapper.nft.NftMapper;
import com.xqboss.apps.vo.category.CategoryAppVo;
import com.xqboss.apps.vo.category.CategoryVo;
import com.xqboss.apps.vo.nft.CategoryVO;
import com.xqboss.apps.mapper.nft.CategoryMapper;
import com.xqboss.common.core.redis.RedisCache;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 分类Service业务层处理
 *
 * @author xqboss
 * @date 2023-08-02
 */
@Service
public class CategoryService extends ServiceImpl<CategoryMapper, Category> {

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private NftMapper nftMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询分类
     *
     * @param id 分类主键
     * @return 分类
     */
    public Category selectCategoryById(Integer id) {
        return categoryMapper.selectCategoryById(id);
    }

    /**
     * 查询分类列表
     *
     * @param category 分类
     * @return 分类
     */
    public List<Category> selectCategoryList(Category category) {
        return categoryMapper.selectCategoryList(category);
    }

    /**
     * 新增分类
     *
     * @param category 分类
     * @return 结果
     */
    public int insertCategory(Category category) {
        Long count = this.lambdaQuery().eq(Category::getName, category.getName()).eq(Category::getTargetType,category.getTargetType()).count();
        Assert.isTrue(count == 0, () -> new ServiceException("分类名称已存在~"));
        category.setCreateTime(DateUtils.getNowDate());
        return categoryMapper.insertCategory(category);
    }

    /**
     * 修改分类
     *
     * @param category 分类
     * @return 结果
     */
    public int updateCategory(Category category) {
        Long count = this.lambdaQuery().ne(Category::getId, category.getId()).eq(Category::getName, category.getName()).eq(Category::getTargetType,category.getTargetType()).count();
        Assert.isTrue(count == 0, () -> new ServiceException("分类名称已存在~"));
        category.setUpdateTime(DateUtils.getNowDate());
        return categoryMapper.updateCategory(category);
    }

    /**
     * 批量删除分类
     *
     * @param ids 需要删除的分类主键
     * @return 结果
     */
    public int deleteCategoryByIds(Integer[] ids) {
        return categoryMapper.deleteCategoryByIds(ids);
    }


    public List<CategoryVO> treeList(Integer targetType) {
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.lambda().eq(Category::getTargetType, targetType);
        List<Category> categoryList = this.list(categoryQueryWrapper);
        if (CollUtil.isEmpty(categoryList)) {
            return new ArrayList<>();
        }
        List<CategoryVO> categoryVOList = new ArrayList<>();
        categoryList.stream().forEach(category -> {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(category, categoryVO);
            categoryVOList.add(categoryVO);
        });
        List<CategoryVO> categoryVOList1 = new ArrayList<>();
        List<CategoryVO> categoryVOList2 = new ArrayList<>();
        List<CategoryVO> categoryVOList3 = new ArrayList<>();
        categoryList.stream().forEach(category -> {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(category, categoryVO);
            if (category.getLevel() == 1) {
                categoryVOList1.add(categoryVO);
            } else if (category.getLevel() == 2) {
                categoryVOList2.add(categoryVO);
            } else if (category.getLevel() == 3) {
                categoryVOList3.add(categoryVO);
            }
        });
        for (CategoryVO categoryVO2 : categoryVOList2) {
            for (CategoryVO categoryVO3 : categoryVOList3) {
                if (categoryVO2.getId() == categoryVO3.getParentId().longValue()) {
                    if (CollectionUtils.isEmpty(categoryVO2.getChildren())) {
                        List<CategoryVO> categoryVOList4 = new ArrayList<CategoryVO>();
                        categoryVOList4.add(categoryVO3);
                        categoryVO2.setChildren(categoryVOList4);
                    } else {
                        if (categoryVO3 != null) {
                            categoryVO2.getChildren().add(categoryVO3);
                        }
                    }
                }
            }
        }

        for (CategoryVO categoryVO1 : categoryVOList1) {
            for (CategoryVO categoryVO2 : categoryVOList2) {
                if (categoryVO1.getId() == categoryVO2.getParentId().longValue()) {
                    if (CollectionUtils.isEmpty(categoryVO1.getChildren())) {
                        List<CategoryVO> categoryVOList4 = new ArrayList<CategoryVO>();
                        categoryVOList4.add(categoryVO2);
                        categoryVO1.setChildren(categoryVOList4);
                    } else {
                        if (categoryVO2 != null) {
                            categoryVO1.getChildren().add(categoryVO2);
                        }
                    }
                }
            }
        }
        return categoryVOList1;
    }

    //****************************************************************************************************************
    //**************************************下面是v1.7.5新增的 藏品/装备/宝盒 分类功能**************************************
    //****************************************************************************************************************

    /**
     * 查询分类列表
     *
     * @param dto 分类
     * @return 分类
     */
    public List<CategoryVo> selectCategoryListNft(CategoryDto dto) {
        return categoryMapper.selectCategoryListNft(dto);
    }

    /**
     * 查询分类列表 App
     *
     * @param dto 分类
     * @return 分类
     */
    public List<CategoryAppVo> selectCategoryListNftApp(CategoryDto dto) {
        List<CategoryAppVo> vo = redisCache.getCacheObject(RedisKey.KEY_MARKET_CATEGORY_TYPE + dto.getNftType());
        if (CollUtil.isEmpty(vo)) {
            vo = categoryMapper.selectCategoryListNftApp(dto);
            redisCache.setCacheObject(RedisKey.KEY_MARKET_CATEGORY_TYPE+dto.getNftType(),vo);
        }
        return vo;
    }

    /**
     * 新增分类
     *
     * @param category 分类
     * @return 结果
     */
    public int insertCategoryNft(Category category) {
        Long count = this.lambdaQuery().eq(Category::getName, category.getName()).eq(Category::getNftType,category.getNftType()).count();
        Assert.isTrue(count == 0, () -> new ServiceException("分类名称已存在~"));
        category.setCreateTime(DateUtils.getNowDate());
        redisCache.deleteObject(RedisKey.KEY_MARKET_CATEGORY_TYPE+category.getNftType());
        return categoryMapper.insertCategory(category);
    }

    /**
     * 修改分类
     *
     * @param category 分类
     * @return 结果
     */
    public int updateCategoryNft(Category category) {
        Long count = this.lambdaQuery().ne(Category::getId, category.getId()).eq(Category::getName, category.getName()).eq(Category::getNftType,category.getNftType()).count();
        Assert.isTrue(count == 0, () -> new ServiceException("分类名称已存在~"));
        category.setUpdateTime(DateUtils.getNowDate());
        redisCache.deleteObject(RedisKey.KEY_MARKET_CATEGORY_TYPE+category.getNftType());
        return categoryMapper.updateCategory(category);
    }


    /**
     * 删除分类信息
     *
     * @param id 分类主键
     * @return 结果
     */
    public int deleteCategoryNftById(Integer id) {
        //删除对应目录
        int i = categoryMapper.deleteCategoryById(id);
        Assert.isTrue(i>0,()->new ServiceException("删除失败~"));
        redisCache.deleteObject(RedisKey.KEY_MARKET_CATEGORY_TYPE+"*");
        //对应关联的nft的分类id置空
        Long count = this.nftMapper.selectCount(new QueryWrapper<Nft>().eq("category_nft_id", id));
        if (count > 0) {
           return this.nftMapper.updateNftCategoryNull(id);
        }
        return i;
    }
}

